﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Threading.Tasks;
using System.Reflection;

namespace OrderManager.Orders
{
    abstract class OrderManagerBase
    {
        public const string ShopType_PaiPai = "拍拍";
        public const string ShopType_WangGou = "网购";
        public const string ShopType_Tmall = "天猫";
        public const string ShopType_TaoBao = "淘宝";

        protected bool isStop = false;
        private Task downloadTask = null;
        private object taskLock = new object();

        public abstract string Type { get; }

        public string ShopName { get; protected set; }

        public event EventHandler OrderDownloadStart;

        public event EventHandler<OrderDownloadEventArgs> OrderDownloading;

        public event EventHandler<DownloadEndEventArgs> OrderDownloadEnd;

        protected virtual void OnOrderDownloadStart()
        {
            if (this.OrderDownloadStart != null)
            {
                this.OrderDownloadStart(this, new EventArgs());
            }
        }

        protected virtual void OnOrderDownloading(OrderDownloadEventArgs e)
        {
            if (this.OrderDownloading != null)
            {
                this.OrderDownloading(this, e);
            }
        }

        protected virtual void OnOrderDownloadEnd(Exception exception)
        {
            if (this.OrderDownloadEnd != null)
            {
                this.OrderDownloadEnd(this, new DownloadEndEventArgs(exception));
            }
        }

        protected void DownloadOrdersTask(OrderDownloadArgs args)
        {
            Exception e = null;
            try
            {
                this.OnOrderDownloadStart();
                this.DownloadOrders(args);
            }
            catch (Exception ex)
            {
                e = ex;
            }
            finally
            {
                lock (this.taskLock)
                {
                    this.isStop = false;
                    this.downloadTask = null;
                }
                this.OnOrderDownloadEnd(e);
            }
        }

        public void StartDownloadOrders(OrderDownloadArgs args)
        {
            lock (this.taskLock)
            {
                if (this.downloadTask != null)
                {
                    throw new InvalidProgramException("已启动下载,无法再次启动");
                }
                this.isStop = false;
                this.downloadTask = Task.Factory.StartNew(() => this.DownloadOrdersTask(args));
            }
        }

        public void StopDownloadOrders()
        {
            Task tmp = null;
            lock (this.taskLock)
            {
                if (this.downloadTask == null)
                {
                    throw new InvalidProgramException("未启动下载，无法停止");
                }
                tmp = this.downloadTask;
                this.isStop = true;
            }
        }

        protected abstract void DownloadOrders(OrderDownloadArgs args);

        public abstract void Initialize(XElement xelement);

        public abstract Order[] GetOrdersByName(string id);

        public abstract Order[] GetOrdersByPhone(string phone);

        public abstract Order[] GetOrdersByNameAndAddress(string name, string address);

        public abstract void Update(string orderID, OrderFlag flag, string address, string sellerComment);

        public static OrderManagerBase[] LoadOrderManagers()
        {
            XDocument xDoc = XDocument.Parse(Properties.Resources.Shops);
            List<OrderManagerBase> orderManagers = new List<OrderManagerBase>();

            foreach (XElement xe in xDoc.Root.Elements("Shop"))
            {
                string strName = xe.Attribute("Name").Value;
                string strAssembly = xe.Attribute("Assembly").Value;
                string strClass = xe.Attribute("Class").Value;

                if (string.IsNullOrWhiteSpace(strName) ||
                    string.IsNullOrWhiteSpace(strClass))
                {
                    continue;
                }

                Assembly assembly = null;

                if (string.IsNullOrWhiteSpace(strAssembly) == false)
                {
                    assembly = Assembly.Load(strAssembly);
                }
                else
                {
                    assembly = typeof(OrderManagerBase).Assembly;
                }
                Type type = assembly.GetType(strClass);

                OrderManagerBase orderManager = Activator.CreateInstance(type) as OrderManagerBase;

                orderManager.ShopName = strName;

                orderManager.Initialize(xe.Elements("Security").First());

                orderManagers.Add(orderManager);
            }

            return orderManagers.ToArray();
        }
    }
}
